package qingyu.ai.common.net;

import android.content.Context;

import com.google.gson.Gson;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;

import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import qingyu.ai.common.Constants;
import qingyu.ai.common.util.SPUtil;
import qingyu.ai.domain.HttpResult;
import qingyu.ai.domain.UserInfoData;

public class TokenInterceptor implements Interceptor {
    private Context mContext;

    public TokenInterceptor(Context mContext) {
        this.mContext = mContext;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();

        if (originalRequest.method().equals("POST")) {
            Response response = chain.proceed(originalRequest);
            if (isTokenExpired(response)) {
                FormBody originalFormBody = (FormBody) originalRequest.body();
                FormBody.Builder newBuilder = new FormBody.Builder();
                for (int i = 0; i < originalFormBody.size(); i++) {
                    newBuilder.add(originalFormBody.name(i), originalFormBody.value(i));
                }
                //获取本地refresh_token
                String refresh_token = SPUtil.getString(Constants.userinfo.refresh_token, Constants.net.DEFAULT_REFRESH_TOKEN);
                HashMap<String, String> map = new HashMap<>();
                map.put("refresh_token", refresh_token);
                HttpResult<UserInfoData> httpResult = new APIFactory(mContext, RetrofitHttpUtil.BASE_URL)
                        .refrashToken(map)
                        .execute().body();

                /**
                 *如果刷新refresh_token失败，则默认为登陆失效，需要重新登陆
                 */
                if (httpResult.code != Constants.net.SUCCESS)
                    throw new APIException(httpResult.code, httpResult.message);

                String access_token = httpResult.payload.getResult().getAccess_token();
                SPUtil.getString(Constants.userinfo.access_token, access_token);
                SPUtil.getString(Constants.userinfo.refresh_token, httpResult.payload.getResult().getRefresh_token());

                //添加新token，重新请求
                newBuilder.add("token", access_token);
                Request newRequest = originalRequest.newBuilder()
                        .method(originalRequest.method(), newBuilder.build())
                        .build();
                return chain.proceed(newRequest);//重新请求
            }
            return response;
        }
        return chain.proceed(originalRequest);
    }

    private static final Charset UTF8 = Charset.forName("UTF-8");


    /**
     * 返回true为无效
     * <p>
     * 通过如下的办法曲线取到请求完成的数据
     * <p>
     * 原本想通过originalResponse.body().string() 但是OKHttp调用string（）就已经关闭IO
     * <p>
     * 然后去看了HttpLoggingInterceptor 的源码,取到请求完成的数据后,根据特定的判断条件去判断token过期
     */
    private boolean isTokenExpired(Response response) {
        try {
            if (response.isSuccessful()) {
                ResponseBody responseBody = response.body();
                BufferedSource source = responseBody.source();
                source.request(Long.MAX_VALUE);
                Buffer buffer = source.buffer();
                Charset charset = UTF8;
                MediaType contentType = responseBody.contentType();
                if (contentType != null) {
                    charset = contentType.charset(UTF8);
                }
                String bodyString = buffer.clone().readString(charset);
                HttpResult httpResult = new Gson().fromJson(bodyString, HttpResult.class);
                return httpResult.code == Constants.net.LOCAL_TOKEN_INVALID;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response.code() == Constants.net.LOCAL_TOKEN_INVALID;
    }
}
